#include "api_server.h"
#include <iostream>
#include <sstream>

namespace nanok {

APIServer::APIServer(Store* store, int port) : store_(store), port_(port), daemon_(nullptr) {
}

APIServer::~APIServer() {
    stop();
}

bool APIServer::start() {
    daemon_ = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port_, nullptr, nullptr,
                              &APIServer::handleRequest, this, MHD_OPTION_END);
    if (daemon_ == nullptr) {
        std::cerr << "Failed to start server on port " << port_ << std::endl;
        return false;
    }
    std::cout << "Server started on port " << port_ << std::endl;
    char chr;
    while (true) {
        chr = getchar();
        if (60 == chr) {
            MHD_stop_daemon(daemon_);
            break;
        }
    }
    return true;
}

void APIServer::stop() {
    if (daemon_) {
        MHD_stop_daemon(daemon_);
        daemon_ = nullptr;
        std::cout << "Server stopped" << std::endl;
    }
}

std::string APIServer::getHandler(const std::string url, const std::map<std::string, std::string>& params) {
    std::string response;
    if (url.compare(0, 6, "/pods/") == 0) {
        // 以 /pods/ 开头的请求，获取某个pod的值
        std::string key = url;
        std::string value;
        if (store_->Get(key, &value)) {
            response = value;
        } else {
            response = "{\"result\": \"Error\", \"message\": \"Failed to get pod info!\"}";
        }
    } else if (url.compare("/pods") == 0) {
        auto pods = store_->List("/pods/");
        response = std::string("[");
        for (size_t i = 0; i < pods.size(); i++) {
            response += pods[i];
            if (i < pods.size() - 1) response += ",";
        }
        response += "]";
    } else if (url.compare("/tasks") == 0) {
        auto tasks = store_->List("/tasks/");
        response = "[";
        for (size_t i = 0; i < tasks.size(); i++) {
            response += tasks[i];
            // if (i < pods.size() - 1) response += ",";
            if (i < tasks.size() - 1) response += ",";
        }
        response += "]";
    } else if (url.compare("/nodes") == 0) {
        auto nodes = store_->List("/nodes/");
        response = std::string("[");
        for (size_t i = 0; i < nodes.size(); i++) {
            response += nodes[i];
            // if (i < pods.size() - 1) response += ",";
            if (i < nodes.size() - 1) response += ",";
        }
        response += "]";
    } else {
        response = "[]";
    }
    for (const auto& param : params) {
        response += param.first + " = " + param.second + "\n";
    }
    return response;
}

std::string APIServer::createPod(const Json::Value& jsonData) {
    std::string response;
    Pod pod;
    Json::StreamWriterBuilder builder;
    builder.settings_["indentation"] = ""; // 禁用缩进（紧凑格式）
    std::string jsonString = Json::writeString(builder, jsonData);
    if (!from_json(jsonString, pod)) {
        response = "{\"result\": \"Error\", \"message\": \"Invalid pod json!\"}";
    }
    if (pod.metadata.namespace_.empty()) {
        pod.metadata.namespace_ = "default";
    }
    std::string key = "/pods/" + pod.metadata.namespace_ + "/" + pod.metadata.name;
    std::string value = to_json(pod);
    if (store_->Create(key, value)) {
        response = value;
        // return sendResponse(connection, response, 201);
    } else {
        response = "{\"result\": \"Error\", \"message\": \"Failed to create pod!\"}";
    }
    return response;
}

std::string APIServer::submitTask(const Json::Value& jsonData) {
    std::string response;
    // 解析出key和value
    std::string key = jsonData["key"].asString();
    Json::StreamWriterBuilder compactWriter;
    compactWriter.settings_["indentation"] = ""; // 设置为空字符串表示紧凑格式
    std::string value = Json::writeString(compactWriter, jsonData["value"]);
    // 保存入LevelDB
    if (store_->Create(key, value)) {
        response = "{\"result\": \"OK\", \"message\": \"for test\"}";
    } else {
        response = "{\"result\": \"Error\", \"message\": \"Failed to store the task object to LevelDB\"}";
    }
    // 生成响应结果
    return response;
}

std::string APIServer::updateTask(const Json::Value& jsonData) {
    std::string response;
    // 解析出key和value
    std::string key = jsonData["key"].asString();
    Json::StreamWriterBuilder compactWriter;
    compactWriter.settings_["indentation"] = ""; // 设置为空字符串表示紧凑格式
    std::string value = Json::writeString(compactWriter, jsonData["value"]);
    // 保存入LevelDB
    if (store_->Update(key, value)) {
        response = "{\"result\": \"OK\", \"message\": \"Update task succeed\"}";
    } else {
        response = "{\"result\": \"Error\", \"message\": \"Failed to update task in LevelDB\"}";
    }
    // 生成响应结果
    return response;
}

std::string APIServer::updatePod(const Json::Value& jsonData) {
    std::string response;
    // 解析出key和value
    std::string key = jsonData["key"].asString();
    Json::StreamWriterBuilder compactWriter;
    compactWriter.settings_["indentation"] = ""; // 设置为空字符串表示紧凑格式
    std::string value = Json::writeString(compactWriter, jsonData["value"]);
    if (store_->Update(key, value)) {
        response = "{\"result\": \"OK\", \"message\": \"Update pod succeed\"}";
    } else {
        response = "{\"result\": \"Error\", \"message\": \"Failed to update pod in LevelDB\"}";
    }
    return response;
}

std::string APIServer::registerNode(const Json::Value& jsonData) {
    std::string response;
    // 解析出key和value
    std::string key = jsonData["key"].asString();
    Json::StreamWriterBuilder compactWriter;
    compactWriter.settings_["indentation"] = ""; // 设置为空字符串表示紧凑格式
    std::string value = Json::writeString(compactWriter, jsonData["value"]);
    if (store_->Create(key, value)) {
        response = "{\"result\": \"OK\", \"message\": \"Register node succeed\"}";
    } else {
        response = "{\"result\": \"Error\", \"message\": \"Failed to register node in LevelDB\"}";
    }
    return response;
}

std::string APIServer::postHandler(const std::string url, const Json::Value& jsonData) {
    std::string response;
    if (url.compare("/createPod") == 0) {
        response = createPod(jsonData);
    } else if (url.compare("/submitTask") == 0) {
        response = submitTask(jsonData);
    } else if (url.compare("/updateTask") == 0) {
        response = updateTask(jsonData);
    } else if (url.compare("/updatePod") == 0) {
        response = updatePod(jsonData);
    } else if (url.compare("/registerNode") == 0) {
        response = registerNode(jsonData);
    }
    return response;
}

MHD_Result APIServer::handleRequest(void* cls, MHD_Connection* connection,
                                   const char* url, const char* method,
                                   const char* /*version*/, const char* upload_data,
                                   size_t* upload_data_size, void** con_cls) {
    APIServer* server = static_cast<APIServer*>(cls);
    // 第一次调用时，初始化连接上下文
    if (*con_cls == nullptr) {
        ConnectionInfo* con_info = new ConnectionInfo();
        // 对于 POST 请求，创建 POST 处理器
        if (strcmp(method, "POST") == 0 || strcmp(method, "PUT") == 0) {
            con_info->post_processor = MHD_create_post_processor(
                connection, 1024, &APIServer::iteratePost, con_info);
        }
        *con_cls = con_info;
        return MHD_YES;
    }
    ConnectionInfo* con_info = static_cast<ConnectionInfo*>(*con_cls);
    // 处理上传数据
    if (*upload_data_size > 0) {
        if (con_info->post_processor) {
            MHD_post_process(con_info->post_processor, 
                            upload_data, *upload_data_size);
        } else {
            // 如果没有 POST 处理器，直接追加数据
            con_info->data.append(upload_data, *upload_data_size);
        }
        *upload_data_size = 0;
        return MHD_YES;
    }
    // 处理完整的请求
    std::string response;
    std::string method_str(method);
    std::string url_str(url);
    if (method_str == "GET") {
        // 创建map来存储查询参数
        std::map<std::string, std::string> params;
        // 使用MHD_get_connection_values获取所有查询参数
        MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, 
                                &APIServer::parseQueryString, &params);
        response = server->getHandler(url, params);
    } 
    else if (method_str == "POST") {
        Json::Value jsonData;
        Json::Reader jsonReader;        
        if (jsonReader.parse(con_info->data, jsonData)) {
            response = server->postHandler(url, jsonData);
        } else {
            response = "Failed to parse JSON data";
        }
    } 
    else {
        response = "Unsupported HTTP method";
    }
    // 创建并发送响应
    MHD_Response* mhd_response = MHD_create_response_from_buffer(
        response.length(), (void*)response.c_str(), MHD_RESPMEM_MUST_COPY);
    MHD_add_response_header(mhd_response, "Content-Type", "text/plain");
    MHD_Result ret = MHD_queue_response(connection, MHD_HTTP_OK, mhd_response);
    MHD_destroy_response(mhd_response);
    // 清理连接信息
    if (con_info->post_processor) {
        MHD_destroy_post_processor(con_info->post_processor);
    }
    delete con_info;
    *con_cls = nullptr;
    return ret;
}

MHD_Result APIServer::iteratePost(void* coninfo_cls, MHD_ValueKind /*kind*/,
                                 const char* /*key*/, const char* /*filename*/,
                                 const char* /*content_type*/, const char* /*transfer_encoding*/,
                                 const char* data, uint64_t /*off*/, size_t size) {
    ConnectionInfo* con_info = static_cast<ConnectionInfo*>(coninfo_cls);
    if (size > 0) {
        con_info->data.append(data, size);
    }
    return MHD_YES;
}

MHD_Result APIServer::parseQueryString(void *cls, MHD_ValueKind /*kind*/, 
                               const char *key, const char *value) {
    // 将cls转换为map指针
    std::map<std::string, std::string>* params = 
        static_cast<std::map<std::string, std::string>*>(cls);
    // 将参数添加到map中
    if (key != nullptr) {
        if (value != nullptr) {
            (*params)[key] = value;
        } else {
            (*params)[key] = ""; // 处理没有值的情况
        }
    }
    return MHD_YES; // 继续迭代
}

}